/*
 * Copyright 2012 Daniel Kurka
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.googlecode.mgwt.expenses.client.activities.ed;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.googlecode.gwtphonegap.client.PhoneGap;
import com.googlecode.gwtphonegap.client.camera.PictureCallback;
import com.googlecode.gwtphonegap.client.camera.PictureOptions;
import com.googlecode.mgwt.expenses.client.ContextProvider;
import com.googlecode.mgwt.expenses.client.ContextProvider.Mode;
import com.googlecode.mgwt.expenses.client.event.AppEvent;
import com.googlecode.mgwt.expenses.client.event.AppEvent.AppEvents;
import com.googlecode.mgwt.expenses.client.event.ExpenseEntryUpdatedEvent;
import com.googlecode.mgwt.expenses.client.misc.I18N;
import com.googlecode.mgwt.expenses.client.rpc.ExpenseDataService;

public class ExpenseDetailActivity extends AbstractActivity implements ExpenseDetailView.Presenter {

	private final ExpenseDetailView view;
	private final ExpenseDataService expenseDataService;
	private final ContextProvider contextProvider;
	private final EventBus eventBus;

	private boolean currentlyEditing;
	private ExpenseDetailDTO currentModel;

	private boolean currentlySaving;
	private final PhoneGap phoneGap;

	@Inject
	public ExpenseDetailActivity(ExpenseDetailView view, ExpenseDataService expenseDataService, ContextProvider contextProvider, EventBus eventBus, PhoneGap phoneGap) {
		this.view = view;
		this.expenseDataService = expenseDataService;
		this.contextProvider = contextProvider;
		this.eventBus = eventBus;
		this.phoneGap = phoneGap;

	}

	@Override
	public void start(AcceptsOneWidget panel, com.google.gwt.event.shared.EventBus eventBus) {

		view.getLeftButton().setText("Expenses");

		if (contextProvider.getMode() == Mode.DISPLAY) {
			currentlyEditing = false;
			view.getEditButton().setText("Edit");
			view.setReadOnly(true);

			view.showCameraButton(false);
		} else {
			currentlyEditing = true;
			view.getEditButton().setText("Save");
			view.setReadOnly(false);

			// are we on a device?
			if (phoneGap.isPhoneGapDevice()) {
				view.showCameraButton(true);
			} else {
				view.showCameraButton(false);
			}

		}

		view.setPresenter(this);
		panel.setWidget(view);

		loadExpense();

	}

	private void loadExpense() {
		String id = contextProvider.getCurrentExpsenseId();
		view.setLoading(true);
		expenseDataService.loadExpenseDetail(id, new AsyncCallback<ExpenseDetailDTO>() {

			@Override
			public void onFailure(Throwable caught) {
				view.setLoading(false);
				AppEvent.fire(eventBus, AppEvents.BACK);
			}

			@Override
			public void onSuccess(ExpenseDetailDTO result) {
				currentModel = result;
				view.setLoading(false);
				renderModel(result);
			}
		});

	}

	@Override
	public void onStop() {
		super.onStop();
		view.setPresenter(null);
	}

	@Override
	public void onEditButtonPressed() {
		if (currentlySaving)
			return;
		if (currentlyEditing) {
			// trigger save

			if (!validateData()) {
				view.showError("Error Validationg Data");
				return;
			}

			readDataIntoModel();
			currentlySaving = true;

			view.showCameraButton(false);
			view.setLoading(true);
			expenseDataService.updateExpense(currentModel, new AsyncCallback<Boolean>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO
					view.showError("can not save data");
					currentlySaving = false;
					view.setLoading(false);
				}

				@Override
				public void onSuccess(Boolean result) {
					// after save
					view.getEditButton().setText("Edit");
					view.setReadOnly(true);
					currentlyEditing = false;
					currentlySaving = false;
					view.setLoading(false);

					renderModel(currentModel);

					imageUrlForSaving = null;

					ExpenseEntryUpdatedEvent.fire(eventBus, currentModel.getId());

				}
			});

		} else {
			view.getEditButton().setText("Save");
			view.setReadOnly(false);
			currentlyEditing = true;

			// are we on a device?
			if (phoneGap.isPhoneGapDevice()) {
				view.showCameraButton(true);
			} else {
				view.showCameraButton(false);
			}

		}

	}

	private boolean validateData() {
		try {
			I18N.NUMBER_FORMAT.parse(view.getAmount().getValue());
		} catch (NumberFormatException e) {
			return false;
		}

		return true;
	}

	private void readDataIntoModel() {

		int amount = (int) Math.round(I18N.NUMBER_FORMAT.parse(view.getAmount().getValue()));
		currentModel.setAmount(amount);
		currentModel.setDate(view.getDate().getValue());
		currentModel.setDescription(view.getDescription().getValue());
		currentModel.setTitle(view.getTitleText().getText());
		if (imageUrlForSaving != null)
			currentModel.setFotoUrl(imageUrlForSaving);

	}

	@Override
	public void onLeftButtonPressed() {
		AppEvent.fire(eventBus, AppEvents.EXPENSES);

	}

	protected void renderModel(ExpenseDetailDTO result) {

		view.getAmount().setValue(I18N.NUMBER_FORMAT.format(result.getAmount()));
		view.getDate().setValue(result.getDate());
		view.getDescription().setValue(result.getDescription());
		view.getTitleText().setText(result.getTitle());

		if (result.getFotoUrl() != null) {
			view.setImageUrl(result.getFotoUrl());
			view.showFoto(true);
		} else {
			view.setImageUrl("");
			view.showFoto(false);
		}

	}

	private String imageUrlForSaving;

	@Override
	public void onCameraButtonPressed() {

		if (!phoneGap.isPhoneGapDevice()) {
			return;

		}

		PictureOptions options = new PictureOptions(70);
		options.setAllowEdit(true);
		options.setTargetHeightInPx(300);
		options.setTargetWidthInPx(300);
		options.setSourceType(PictureOptions.PICTURE_SOURCE_TYPE_CAMERA);
		options.setDestinationType(PictureOptions.DESTINATION_TYPE_FILE_URI);

		phoneGap.getCamera().getPicture(options, new PictureCallback() {

			@Override
			public void onSuccess(String data) {
				imageUrlForSaving = data;
				view.setImageUrl(data);
				view.showFoto(true);

			}

			@Override
			public void onFailure(String message) {
				// TODO Auto-generated method stub

			}
		});

	}
}
